import Vue from 'vue'
import Vuex from 'vuex'
import { maxRetryTimes } from '@/config/index'
import api from '@/api/index'

const professions = [
  {
    name: '医学',
    desc: '听说学医的，都不用睡觉，全凭一口仙气吊着。'
  },
  {
    name: '建筑学',
    desc: '做得了模型，画得来正图，上要提笔大师理论，下要基层做调研。'
  },
  {
    name: '物理专业',
    desc: '据说补考量子物理和量子力学时，还能看见前几届的师兄师姐。'
  },
  {
    name: '计算机',
    desc: '我们不约维修电脑，不管是台式还是笔记本，谢谢！'
  },
  {
    name: '电气工程',
    desc: '始终无法回应那句“我家电视/冰箱又坏了，快来帮我修一下！”'
  },
  {
    name: '会计学',
    desc: '少写一个点，验算累瞎眼；多写一个零，验算到天明。'
  },
  {
    name: '法学',
    desc: '根本停不下来，背书背得做梦都在被法理学追着打。'
  },
  {
    name: '土木工程',
    desc: '不是在工地，就是在去工地的路上。'
  },
  {
    name: '中文专业',
    desc: '不给孩子起名，不认识生僻字，不代写论文，当然，付费除外。'
  },
  {
    name: '历史专业',
    desc: '不考古不盗墓，不会鉴定文物，可能也不知道甄嬛怎么死的。'
  },
  {
    name: '心理专业',
    desc: '不是周公不会解梦，不会算命也不会催眠。'
  },
  {
    name: '数学',
    desc: '不懂怎么买最划算，问我不如珠心算。'
  },
  {
    name: '农林专业',
    desc: '不种地也不种树，学校不发大米，花蔫了也别找我。'
  },
  {
    name: '化学专业',
    desc: '不会制毒不会炼金，不能变成绿巨人。'
  }
]

const schools = [
  {
    name: '上海交通大学',
    bg: require('../assets/schoolsbg/上交大.jpeg')
  },
  {
    name: '中山大学',
    bg: require('../assets/schoolsbg/中山.jpg')
  },
  {
    name: '中国人民大学',
    bg: require('../assets/schoolsbg/人大.png')
  },
  {
    name: '中科大',
    bg: require('../assets/schoolsbg/中科大.jpg')
  },
  {
    name: '北京大学',
    bg: require('../assets/schoolsbg/北大.png')
  },
  {
    name: '南开大学',
    bg: require('../assets/schoolsbg/南开大学.png')
  },
  {
    name: '厦门大学',
    bg: require('../assets/schoolsbg/厦大.jpg')
  },
  {
    name: '哈佛大学',
    bg: require('../assets/schoolsbg/哈佛.png'),
    profession: {
      name: '心理学',
      desc: '最早的实验心理学家之一William James创立，美排名第三。'
    }
  },
  {
    name: '哈工大',
    bg: require('../assets/schoolsbg/哈工大.jpg')
  },
  {
    name: '复旦大学',
    bg: require('../assets/schoolsbg/复旦.jpg')
  },
  {
    name: '四川大学',
    bg: require('../assets/schoolsbg/川大.jpeg')
  },
  {
    name: '忍者学院',
    bg: require('../assets/schoolsbg/忍者学校.jpg'),
    profession: {
      name: '忍术',
      desc: '据说忍术的精髓是一套切实可行的强大精神力量修练方法~'
    }
  },
  {
    name: '斯坦福大学',
    bg: require('../assets/schoolsbg/斯坦福.jpg'),
    profession: {
      name: '环境工程',
      desc: '斯坦福是环境类专业顶级院校，位居美国环境工程专业第一。'
    }
  },
  {
    name: '武汉大学',
    bg: require('../assets/schoolsbg/武大.jpg')
  },
  {
    name: '浙江大学',
    bg: require('../assets/schoolsbg/浙大.png')
  },
  {
    name: '清华大学',
    bg: require('../assets/schoolsbg/清华.jpg')
  },
  {
    name: '剑桥大学',
    bg: require('../assets/schoolsbg/牛津.jpg'),
    profession: {
      name: '自然科学',
      desc: '剑桥大学最大的系，选课好像在玩RPG游戏，不停升级和转职！'
    }
  },
  {
    name: '霍格茨沃学院',
    bg: require('../assets/schoolsbg/霍格沃茨.jpg'),
    profession: {
      name: '魔法学',
      desc: '请教给我们知识，不论我们是谢顶的老人，还是跌伤膝盖的孩子~'
    }
  },
  {
    name: '麻省理工学院',
    bg: require('../assets/schoolsbg/麻省理工.jpg'),
    profession: {
      name: '电子工程',
      desc: '电子工程是MIT最强理工学院的最强专业之一。'
    }
  },
  {
    name: '龙城大学',
    bg: require('../assets/schoolsbg/龙城.jpg'),
    profession: {
      name: '生物工程技术',
      desc: '想要选沈教授的课一定要开加速器！学校教务系统会爆炸的说~'
    }
  }
]

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    photo: '',
    result: [], // 用来存储确认页图片缓存
    randomId: '',
    randomBg: '',
    randomSchoolName: '',
    randomProfessionName: '',
    randomProfessionDesc: '',
    blockedRequestName: new Set(),
    resultLen: 0,
    actionId: 0,
    requestInterval: 1000,
    faceId: '', // 用来存储上传页给后端上传的图片返回的id
    isResultLoading: false,
    correctFace: true, // 用户上传的图片是否为人像,
    gender: false
  },
  mutations: {
    SET_PHOTO (state, val) {
      state.photo = val
    },
    SET_RESULT (state, val) {
      state.result = val
    },
    CLEAR_RESULT (state) {
      state.result = {}
      state.blockedRequestName = new Set()
      state.resultLen = 0
      state.actionId++
    },
    REFRESH_ACTION_ID (state) {
      state.actionId++
    },
    SET_REQUEST_INTERVAL (state, val) {
      state.requestInterval = val
    },
    SET_FACE_ID (state, id) {
      state.faceId = id
    },
    SET_GENDER (state, val) {
      state.gender = val
    },
    SET_CORRECT_FACE (state, val) {
      state.correctFace = val
    },
    SET_RANDOMID (state, val) {
      state.randomId = val
      state.randomBg = schools[val].bg
      state.randomSchoolName = schools[val].name
      if (schools[val].profession) {
        state.randomProfessionName = schools[val].profession.name
        state.randomProfessionDesc = schools[val].profession.desc
      } else {
        const randomProfessionIndex = Math.floor(Math.random() * professions.length)
        state.randomProfessionName = professions[randomProfessionIndex].name
        state.randomProfessionDesc = professions[randomProfessionIndex].desc
      }
    },
    ADD_BLOCK_REQUEST (state, req) {
      state.blockedRequestName.add(req)
    },
    REMOVE_BLOCK_REQUEST (state, req) {
      state.blockedRequestName.delete(req)
    },
    SET_RESULT_LOADING (state, val) {
      state.isResultLoading = val
    }
  },
  actions: {
    setPhoto ({ commit }, val) {
      commit('SET_PHOTO', val)
    },
    setFaceId ({ commit }, val) {
      commit('SET_FACE_ID', val)
    },
    clearResult ({ commit }) {
      commit('CLEAR_RESULT')
      commit('REFRESH_ACTION_ID')
    },
    clearFaceId ({ commit }) {
      commit('SET_FACE_ID', '')
    },
    setResultLoading ({ commit }, val) {
      commit('SET_RESULT_LOADING', val)
    },
    uploadFace ({ commit }, photo) {
      // 由于需要等到点击提交键才会提示用户，但是用户提交后就已经开始上传，提升体验，因此需要先存储下状态，等提交照片时才做判断
      commit('SET_CORRECT_FACE', true)
      return api.uploadFace({
        image: photo
      }).then(res => {
        if (!res.error) {
          commit('SET_GENDER', res.gender === 1)
          commit('SET_FACE_ID', res.merge_id)
        } else {
          // commit('SET_CORRECT_FACE', false)
          throw new Error(res.error)
        }
      })
    },
    stopGetMergedFace ({ commit }) {
      commit('REFRESH_ACTION_ID')
    },
    getRandomSchool ({ commit, state }) {
      // 随机一个学校
      const randomId = Math.floor(Math.random() * schools.length)
      commit('SET_RANDOMID', randomId)
      const image = new Image()
      image.src = state.randomBg
      // 等待图片加载完成，用于await
      return new Promise((resolve, reject) => {
        // 20秒未加载出来则会弹窗显示错误
        const timeoutId = setTimeout((reject) => {
          reject(-10000)
        }, 20000)
        image.onload = () => {
          clearTimeout(timeoutId)
          resolve()
        }
      })
    },
    async getMergedFace ({ commit, state }, index = 0) {
      const faceId = state.faceId
      const gender = state.gender
      const result = state.result
      // 所有的模板id，目前男女使用同一套模板
      const modelIds = {
        male: [
          'qc_100515_142139_85',
          'qc_100515_142147_86',
          'qc_100515_142228_88',
          'qc_100515_142126_84',
          'qc_100515_145114_89'
        ],
        female: [
          'qc_100515_142126_84',
          'qc_100515_145114_89',
          'qc_100515_142139_85',
          'qc_100515_142147_86',
          'qc_100515_142228_88'
        ]
      }
      window._hmt.push(['_trackEvent', '结果页', 'result', gender ? '预测结果-默认男生' : '预测结果-默认女生'])
      // 单性别的模板id
      const genderModelId = modelIds[gender ? 'male' : 'female'][index]
      let j = maxRetryTimes
      // 一次加载失败，多尝试几次
      while (j--) {
        const res = await api.mergeFace({
          model_id: genderModelId,
          merge_id: faceId
        })
        if (res.error && res.error !== 2002) {
          throw new Error(res.message)
        }
        if (res.result) {
          result[index] = 'data:image/jpg;base64,' + res.result
          return result[index]
        }
        if (!result[index]) throw new Error(res)
      }
      commit('SET_RESULT', result)
    }
  },
  getters: {
    photo (state) {
      return state.photo
    },
    result (state) {
      return state.result
    },
    resultLen (state) {
      return state.resultLen
    },
    faceId (state) {
      return state.faceId
    },
    isResultLoading (state) {
      return state.isResultLoading
    },
    correctFace (state) {
      return state.correctFace
    },
    randomBg (state) {
      return state.randomBg
    },
    randomProfessionDesc (state) {
      return state.randomProfessionDesc
    },
    randomProfessionName (state) {
      return state.randomProfessionName
    },
    randomSchoolName (state) {
      return state.randomSchoolName
    }
  }
})
